#define _CRT_SECURE_NO_WARNINGS 1
#include "string.h"

void string::swap(string& s) {
	std::swap(_str, s._str);
	std::swap(_size, s._size);
	std::swap(_capacity, s._capacity);
}

void string::reserve(size_t n) {
	if (n > _capacity) {
		char* tmp = new char[n + 1];
		memcpy(tmp, _str, _size + 1);
		delete[] _str;
		_str = tmp;
		_capacity = n;
	}
}

void string::push_back(char c) {
	if (_size == _capacity) {
		reserve(_capacity == 0 ? 5 : _capacity * 2);
	}
	_str[_size] = c;
	_size++;
	_str[_size] = '\0';
}

string& string::append(const char* s) {
	size_t len = strlen(s);
	if (_size + len > _capacity) {
		reserve(_capacity == 0 ? len : _capacity + len);
	}
	memcpy(_str + _size, s, len + 1);
	_size += len;
	return *this;
}

string& string::append(const char c) {
	push_back(c);
	return *this;
}

string& string::operator += (const string& s) {
	return append(s._str);
}

string& string::operator += (const char* s) {
	return append(s);
}

string& string::operator += (char c) {
	return append(c);
}

// ads	adsxx	t
// ads	ads		f
// adsxx ads	f
bool string::operator< (string& str) {
	int tem = memcmp(_str, str._str, _size < str._size ? _size : str._size);
	return tem == 0 ? _size < str._size : tem < 0;
}

bool string::operator== (string& str) {
	return _size == str._size
		&& memcmp(_str, str._str, _size) == 0 ? true : false;
}

bool string::operator!= (string& str) {
	return !(*this == str);
}

bool string::operator<= (string& str) {
	return *this < str || *this == str;
}

bool string::operator> (string& str) {
	return !(*this <= str);
}

bool string::operator>= (string& str) {
	return !(*this < str);
}

string& string::insert(size_t pos, const string& str) {
	size_t end = _size;
	size_t n = str._size;
	if (n + _size > _capacity) {
		reserve(_capacity == 0 ? n : n + _size);
	}

	while (end >= pos && end != string::npos) {
		_str[end + n] = _str[end];
		end--;
	}

	_size += n;
	memcpy(_str + pos, str._str, n);
	return *this;
}

string& string::insert(size_t pos, const char* s) {
	size_t end = _size;
	size_t n = strlen(s);
	if (n + _size > _capacity) {
		reserve(_capacity == 0 ? n : n + _size);
	}

	while (end >= pos && end != string::npos) {
		_str[end + n] = _str[end];
		end--;
	}

	_size += n;
	memcpy(_str + pos, s, n);
	return *this;
}

string& string::erase(size_t pos, size_t len) {
	assert(pos <= _size);
	size_t end = _size;
	if (len != npos && pos + len < end) {
		while (pos + len < end) {
			_str[pos] = _str[pos + len];
			pos++;
		}
	}
	_size = pos;
	_str[_size] = '\0';
	return *this;
}

size_t string::find(const char* s, size_t pos) const {
	char* find = strstr(_str + pos, s);
	if (find == NULL) {
		return npos;
	}
	else {
		return find - _str;
	}
}

string string::substr(size_t pos, size_t len) const {
	size_t n = len;
	if (len == npos || pos + len > _size) {
		n = _size - pos;
	}
	string s;
	s.reserve(n);
	for (int i = 0; i < n; i++) {
		s += _str[pos++];
	}
	return s;
}

ostream& xy::operator<< (ostream& out, const string& str) {
	for (auto ch : str)
	{
		out << ch;
	}

	return out;
}

istream& xy::operator>> (istream& in, string& str) {
	str.clear();
	char ch = in.get();
	while (ch == ' ' || ch == '\n') {
		ch = in.get();
	}
	char buf[128];
	int i = 0;
	while (ch != ' ' && ch != '\n') {
		buf[i++] = ch;
		if (i == 127) {
			buf[127] = '\0';
			str += buf;
			i = 0;
		}
		ch = in.get();
	}
	if (i > 0) {
		buf[i] = '\0';
		str += buf;
	}
	return in;
}